package com.zhisheng.redishello.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.zhisheng.redishello.entity.Product;
import com.zhisheng.redishello.mapper.ProductMapper;
import com.zhisheng.redishello.service.ProductService;
import com.zhisheng.redishello.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * (Product)表服务实现类
 *
 * @author 全哥
 * @since 2025-10-20 16:11:05
 */
@Service("productService")
public class ProductServiceImpl implements ProductService {
    @Resource
    private ProductMapper productMapper;

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public R<Product> selectProductById(Long pid) {
        /*
        1: 从redis中查询商品信息;
        2: 查到了,转成商品对象返回
        3: 查不到,去数据库查询
        4: 查询到了,转json字符串再存入redis一份,并返回
        5: 如果mysql也没有查询到
        说明商品id不对!!!
        (缓存穿透,可以临时在redis中存一个空对象,定时过期)
         */
        //1: 从redis中查询商品信息;
        ValueOperations forValue = redisTemplate.opsForValue();
        Object o = forValue.get("p:" + pid);
        //2: 查到了,转成商品对象返回
        Product product = null;
        if(o == null){
            // 说明redis中,没有这个商品信息,去mysql查一下
             product= productMapper.selectById(pid);
            System.out.println("------------------------------------------从数据库查询:"+pid+"-------------------------------------------------------");
            // 判断 mysql中是否查询到了
            if(product == null){
                // 说明商品id不对!!!
                //(缓存穿透,可以临时在redis中存一个空对象,定时过期)
                forValue.set("p:"+pid,"error", Duration.between(LocalDateTime.now(),LocalDateTime.now().plusMinutes(3)));
            }else {
                // 说明查询到了, 转json,存 5分钟
                forValue.set("p:"+pid, JSONObject.toJSONString(product),5, TimeUnit.MINUTES);
            }
        }else {
            // 说明redis查询的结果 不是 null
            if(!"error".equals(o)){
                product=JSONObject.parseObject(o.toString(),Product.class);
            }
        }
        return R.success(product);
    }
}
